#define _GNU_SOURCE
#include "app_serial.h"
#include "log.h"

/**
 *
 * 设置波特率  (为蓝牙调试使用)
 */
int app_serial_set_baudrate(Device *device, SerialBaudRate baudrate)
{
    // 注意设值 检查g成功失败
    // 1 取出termios 的全部属性 get
    struct termios termios_attr;
    tcgetattr(device->fd, &termios_attr);

    // 2 对属性进行修改
    // 修改波特率
    cfsetspeed(&termios_attr, baudrate);

    // 3  写入属性 set
    int ret= tcsetattr(device->fd, TCSAFLUSH, &termios_attr);

    return ret;
}

/**
 * 设置串口校验位
 */
static int app_serial_set_parity(Device *device, SerialParity parity)
{
    // 注意设值 检查g成功失败
    // 1 取出termios 的全部属性 get
    struct termios termios_attr;
    tcgetattr(device->fd, &termios_attr);

    // 2 对属性进行修改
    // 修改奇偶位
    termios_attr.c_cflag &= ~(PARENB | PARODD); // 清除校验位、
    termios_attr.c_cflag |= parity;             // 设置校验位

    // 3  写入属性 set
    tcsetattr(device->fd, TCSAFLUSH, &termios_attr);

    return 0;
}

static int app_serial_set_stopbit(Device *device, SerialStopBits stopbit)
{
    // 注意设值 检查g成功失败
    // 1 取出termios 的全部属性 get
    struct termios termios_attr;
    tcgetattr(device->fd, &termios_attr);

    // 2 对属性进行修改
    // 修改停止位
    termios_attr.c_cflag &= ~CSTOPB; // 清除停止位
    termios_attr.c_cflag |= stopbit; // 设置停止位

    // 3  写入属性 set
    tcsetattr(device->fd, TCSAFLUSH, &termios_attr);

    return 0;
}

/**
 * 还原原始状态
 */
static int app_serial_makeraw(Device *device)
{
    // 注意设值 检查g成功失败
    // 1 取出termios 的全部属性 get
    struct termios termios_attr;
    tcgetattr(device->fd, &termios_attr);

    // 2 恢复原始状态
    cfmakeraw(&termios_attr);

    // 3  写入属性 set
    tcsetattr(device->fd, TCSAFLUSH, &termios_attr);
    return 0;
}

/**
 * 设置阻塞、非阻塞模式  (为蓝牙调试使用)
 */
int app_serial_set_block(Device *device, int block)
{
    // 1 取出termios 的全部属性 get
    struct termios termios_attr;
    tcgetattr(device->fd, &termios_attr);

    // 2  设置非阻塞状态
    if (block)
    {
        termios_attr.c_cc[VTIME] = 0; // 死等
        termios_attr.c_cc[VMIN] = 1;  // 至少有几个字符
    }
    else
    {
        termios_attr.c_cc[VTIME] = 2; //  0.2秒  每1=0.1秒
        termios_attr.c_cc[VMIN] = 0;  // 没有也可以
    }

    // 3  写入属性 set
    tcsetattr(device->fd, TCSAFLUSH, &termios_attr);
}

/**
 * 给设备进行串口初始化配置
 */
int app_serial_init(Device *device)
{   
    log_info("app_serial_init");
    //定性串口e设备
    device->dev_type = DEVICE_TYPE_SERIAL;
    // 还原
    app_serial_makeraw(device);
    // 1 波特率 2 奇偶校验位 5 停止位
    int ret= app_serial_set_baudrate(device, BR_115200);
    if(ret ==0)
    {
        log_info("app_serial_set_baudrate success");
    }    
    app_serial_set_parity(device, Parity_None);
    app_serial_set_stopbit(device, StopBit_One);
    // flush
    ret=  tcflush(device->fd, TCIOFLUSH);
    if(ret ==0)
    {
        log_info("app_serial_init success");
    }
    return ret;
}